package com.pwt.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author dw
 * @date 2021/12/29 21:59
 * @Description
 */
public class MathUtil {

    public static Double avg(List<Double> list){
        if(list == null && list.size() < 1){
            return 0D;
        }
        Double avg = 0D;
        for ( Double d:list) {
            if(d != null){
                avg = addDouble(avg,d);
            }
        }
        return divDouble(avg,list.size()*1.00);
    }

    public static List<Double> RXbar(List<Double> list){
        List<Double> rxList = new ArrayList<>();
        if(list == null || list.size() < 1) return null;

        for (int i = 0; i < list.size(); i++) {
            if(i == (list.size()-1)){
                return rxList;
            }else{
                rxList.add(Math.abs(subDouble(list.get(i),list.get(i+1))));
            }
        }
        return rxList;
    }


    public static Double addDouble(Double a,Double b){
        BigDecimal d1 = new BigDecimal(Double.toString(a));
        BigDecimal d2 = new BigDecimal(Double.toString(b));
        return d1.add(d2).doubleValue();
    }

    public static Double subDouble(Double a,Double b){
        BigDecimal d1 = new BigDecimal(Double.toString(a));
        BigDecimal d2 = new BigDecimal(Double.toString(b));
        return d1.subtract(d2).doubleValue();
    }

    public static Double mulDouble(Double a,Double b){
        BigDecimal d1 = new BigDecimal(Double.toString(a));
        BigDecimal d2 = new BigDecimal(Double.toString(b));
        return d1.multiply(d2).doubleValue();
    }

    public static Double divDouble(Double a,Double b){
        if(b > 0 || b < 0){
            BigDecimal d1 = new BigDecimal(Double.toString(a));
            BigDecimal d2 = new BigDecimal(Double.toString(b));
            return d1.divide(d2,2, RoundingMode.HALF_UP).doubleValue();
        }
        return 0.00;
    }

    /**
     * 获取中位数
     * @return
     */
    public static Double median(List<Double> list){
        if(list == null || list.size() < 1) return null;
        Integer size = list.size();
        Double median = 0.00;
        if(size % 2 == 0){//偶数
            median = (list.get(size/2) + list.get(size/2-1))/2;
        }else if(size % 2 == 1){//奇数
            median = list.get((size-1)/2);
        }
        return median;
    }


    //方差s^2=[(x1-x)^2 +...(xn-x)^2]/n 或者s^2=[(x1-x)^2 +...(xn-x)^2]/(n-1)
    public static double Variance(Double[] x) {
        int m=x.length;
        double sum=0;
        for(int i=0;i<m;i++){//求和
            sum+=x[i];
        }
        double dAve=sum/m;//求平均值
        double dVar=0;
        for(int i=0;i<m;i++){//求方差
            dVar+=(x[i]-dAve)*(x[i]-dAve);
        }
        return dVar/m;
    }

    //标准差σ=sqrt(s^2)
    public static double StandardDiviation(Double[] x) {
        int m=x.length;
        double sum=0;
        for(int i=0;i<m;i++){//求和
            sum+=x[i];
        }
        double dAve=sum/m;//求平均值
        double dVar=0;
        for(int i=0;i<m;i++){//求方差
            dVar+=(x[i]-dAve)*(x[i]-dAve);
        }
        //reture Math.sqrt(dVar/(m-1));
        return Math.sqrt(dVar/m);
    }

    //百分位数
    public static double percentile(double[] data,double p){
        int n = data.length;
        Arrays.sort(data);
        double px =  p*(n-1);
        int i = (int)java.lang.Math.floor(px);
        double g = px - i;
        if(g==0){
            return data[i];
        }else{
            return (1-g)*data[i]+g*data[i+1];
        }
    }

}
